package org.zn.mvcbase.exception;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * @ProjectName:zqdk-mvcbase
 * @Description: 
 * @author: 周楠
 * @date 2017年3月3日 下午4:06:46
 */

public class CommonExceptionResolver //implements HandlerExceptionResolver 
{

    private String charset="UTF-8";
	
	private String defaultExceptionPage;
	
	private Map<String,HttpMessageConverter<?>> converterMap;
	
	
	private ExceptionResponseHandler erhandler;
	
	@Autowired	
	private ExceptionResponseStateFactory stateFactory;
	
	@Autowired
	private ExceptionResponseMessageFactory ermFactory;
	
	public String getCharset() {
		return charset;
	}
	public void setCharset(String charset) {
		this.charset = charset;
	}
	public String getDefaultExceptionPage() {
		return defaultExceptionPage;
	}
	public void setDefaultExceptionPage(String defaultExceptionPage) {
		this.defaultExceptionPage = defaultExceptionPage;
	}

	public Map<String, HttpMessageConverter<?>> getConverterMap() {
		return converterMap;
	}

	public void setConverterMap(Map<String, HttpMessageConverter<?>> converterMap) {
		this.converterMap = converterMap;
	}


	public ExceptionResponseHandler getErhandler() {
		return erhandler;
	}
	public void setErhandler(ExceptionResponseHandler erhandler) {
		this.erhandler = erhandler;
	}
	
	public ExceptionResponseMessageFactory getErmFactory() {
		return ermFactory;
	}
	public void setErmFactory(ExceptionResponseMessageFactory ermFactory) {
		this.ermFactory = ermFactory;
	}
	
	
	@PostConstruct
	public void init(){
		

		Map<String,HttpMessageConverter<?>> baseconverterMap=new HashMap<>();
		
		baseconverterMap.put("jsonConverter", new MappingJackson2HttpMessageConverter());
		baseconverterMap.put("byteArrayConverter", new ByteArrayHttpMessageConverter());
		baseconverterMap.put("allEncompassingFormConverter", new AllEncompassingFormHttpMessageConverter());
		baseconverterMap.put("sourceHttpConverter", new  SourceHttpMessageConverter<Source>());
		if(converterMap!=null){baseconverterMap.putAll(converterMap);}	
		converterMap=baseconverterMap;
		
		
		if(stateFactory==null){
			stateFactory=new ExceptionResponseStateFactory();
			stateFactory.init();
		}

		if(erhandler==null){
			erhandler=new ExceptionResponseHandler();
		
		}

		if(erhandler.getFactory()==null){
			erhandler.setFactory(stateFactory);
		}
		
	}

	
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handlerMethod,
			Exception exception) {

	    
		ExceptionResponseMessage erm=ermFactory.getExceptionResponseMessage(exception);
	    
		Map<String, Object> model=erm.getMessageModle(request,exception);
		
		
		
	    ModelAndView mav= erhandler.exceptionResponse(request, response, converterMap, model);
	    
	    
	    if(mav!=null) {
	    	
	    	if(model.get(ExceptionResponseMessage.ERRORPAGE_KEY)==null) {
	    		
	    		mav.setViewName(defaultExceptionPage);
	    		
	    	}else {
	    		
	    		mav.setViewName(model.get(ExceptionResponseMessage.ERRORPAGE_KEY).toString());
	    		
	    	}
	    	
	    }
	    
	    
		return mav;
	}
	
	
	
	
	

}
